#include <iostream>
#include <fstream>
#include <vector>
#include "utils.h"
#include "splines.h"
#include "sets.h"
#include "combine.h"
using namespace std;


void salida(const vector<bomba>& res, ostream& out) {
	forn(i,res.size()) {
		out.precision(20);
		out << res[i].t << "   " << res[i].x << " " << res[i].y << endl;
	}
}


ostream& operator<<(ostream& o, const pol& p) {
	bool nf=true;
	dforn(i,p.size()) {
		if (p[i]==0.0) continue;
		if (nf) nf=false; else o << " + ";
		o << p[i];
		if (i>0) o << "*x";
		if (i>1) o << "^" << i;
	}
	return o;
}

int main(int argc, char *argv[]) {
	if (argc!=3 && argc!=2) {
		cout << "USO: tp4 archivoEntrada [archivoSalida]" << endl;
		return 1;
	}
	int n; //cantidad de misiles
	int m; //mediciones de cada misil
	ifstream in(argv[1]);
	in >> n >> m;
	vector< pair<pol,pol> > ptsP(n);
	cerr << "Calculando trayectorias" << endl;
	forn(i,n) {
		vector<double> x(m),y(m);
		forn(j,m) in >> x[j] >> y[j];
		//app devuelve un spline: m-1 polinomios 0,1,...,(m-2)
		spline sx=app(x),sy=app(y);
		ptsP[i]=make_pair(sx[m-2],sy[m-2]);
	}
	int b; //cantidad de bombas
	double r; //radio de las bombas
	double R; //radio del planeta
	in >> b >> r >> R;
	R+=r+eps*2.0; //lugares prohibidos
	cerr << "Buscando potenciales bombas" << endl;
	vector<pair<bset,bomba> > bs = getSets(ptsP, r, m+eps, 2.0*(m-eps), 
		200, //disc
		10, //iter
		1000, //csets
		1, //alpha
		R);
	cerr << "Combinando bombas" << endl;
	vector<bomba> res = getBest(bs, b, 100, n);
	cerr << "Escribiendo salida" << endl;
	if (argc==2) salida(res,cout);
	else {
		ofstream out(argv[2]);
		salida(res,out);
	}
	bset muere;
	forn(i,res.size())forn(j,n) {
		double x=res[i].x-eval(ptsP[j].first,res[i].t);
		double y=res[i].y-eval(ptsP[j].second,res[i].t);
		if (x*x+y*y<=r*r) muere[j]=true;
	}
	cerr << "Misiles muertos: " << muere.count() << "/" << n << " (";
	forn(i,n) cerr << (muere[i]?'1':'0');
	cerr << ")" << endl;
	return 0;
}
